/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>

#include "BasicType.h"
#include "TsCaster.h"
#include "SharedPtr.h"
#include "TFileUtil.h"
#include <assert.h>
#include "TByteBuffer.h"
#include <errno.h>



static bool hasPrefix(const uint8_t* data, int size)
{
    assert(size >= 4);
    if ((data[0] == 0) && (data[1] == 0))
    {
        if ((data[2] == 0) && (data[3] == 1))
        {
            return true;
        }
        if (data[2] == 1)
        {
            return true;
        }
    }
    return false;
}

struct CasterGuard
{
public:
    CasterGuard()
    {
        tscaster_init();
    }

    ~CasterGuard()
    {
        tscaster_quit();
    }
};

struct PacketHeader
{
	int prefix;
	int type;
	int size;
	int64_t pts;
	int duration;
	int flags;
};


int main(int argc, char** argv)
{
	int hdrSize = sizeof(PacketHeader);

	if (argc <= 1)
    {
        return EINVAL;
    }

    char* filename = argv[1];
	FILE* file = fopen(filename, "rb");
	if (!file)
	{
		return ENOENT;
	}

    CasterGuard casterGuard;
	
    MFormat fmt;
    memset(&fmt, 0, sizeof(fmt));
    
	fmt.codec = MCODEC_H265;
	fmt.width = 1920;
	fmt.height = 1080;
	fmt.profile = 66;
	fmt.framerate = 25;
	fmt.clockRate = 1000000;

	fmt.audioCodec = MCODEC_AAC;
	fmt.channels = 1;
	fmt.sampleRate = 48000;
	fmt.audioProfile = 1;
	fmt.audioRate = 1000000;

	uint8_t aacConfig[2] = {0x11, 0x88};
	fmt.config = aacConfig;
	fmt.configSize = sizeof(aacConfig);

	int rc = 0;
	tscaster_t handle = INVALID_CASTER;
    rc = tscaster_open(&handle, TSCASTER_PROTOCOL_UDP, 0, &fmt);
	if (rc != 0)
	{
		fclose(file);
		return ENODEV;
	}

    tscaster_add_target(handle, "127.0.0.1", 8001);

	PacketHeader hdr;
	comn::ByteBuffer buffer;

	int count = 1000;
    while (true)
    {
		//count--;
		if (count <= 0)
		{
			break;
		}

		long pos = ftell(file);
		std::cout << "pos: " << pos << std::endl;

		if (pos >= 0x31d986a)
		{
			std::cout << "\n";
		}

		memset(&hdr, 0, sizeof(hdr));
		int length = fread(&hdr, 1, sizeof(hdr), file);
		if (length != sizeof(hdr))
		{
			std::cout << "invalid header.\n";
			break;
		}

		printf("pkt. type:%d, size:%d, flags:%d, duration:%d, pts:%I64d\n", hdr.type, hdr.size, hdr.flags, hdr.duration, hdr.pts);

		if (hdr.size == 0)
		{
			printf("empty packet.\n");
			continue;
		}

		if (hdr.size < 0 || hdr.size > 1024 * 1024* 2)
		{
			std::cout << "eof: " << feof(file) << std::endl;
			std::cout << "pos:" << ftell(file) << std::endl;

			break;
		}


		buffer.ensure(hdr.size);
		length = fread(buffer.data(), 1, hdr.size, file);
		if (length != hdr.size)
		{
			std::cout << "invalid package.\n";
			break;
		}

		if (length > 0x04)
		{
			int prefix = *(int*)buffer.data();
			if (prefix == 0x01020304)
			{
				std::cout << "bad data." << std::endl;
				std::cout << "eof: " << feof(file) << std::endl;
				std::cout << "pos:" << ftell(file) << std::endl;

				break;
			}
		}

		MPacket pkt;
		pkt.type = hdr.type;
		pkt.pts = hdr.pts;
		pkt.duration = hdr.duration;
		pkt.flags = hdr.flags;

		pkt.data = buffer.data();
		pkt.size = hdr.size;
		
		tscaster_write(handle, &pkt);

		//int delay = clockDelay.getDelay(pkt.pts);
		//	
		//if (delay > 10)
		//{
		//	av_usleep(delay * 1000);
		//}

		//::Sleep(10);
    }

	std::cout << "enter any key to exit.\n";
    std::cin.get();

    tscaster_close(handle);
    handle = INVALID_CASTER;

	fclose(file);

	return 0;
}




